package model;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Matrix3D implements Matrix {
	private int size;
	private int [][][] matrix;
	
	public Matrix3D(int size) {
		this.size = size;
		matrix = new int[size][size][size];
	}
	
	/** A matrixunkhoz hozzaadunk egy parameterkent megadott matrixot.
	 * */
	public Matrix3D sum(Matrix3D a) throws MatrixException {
		Matrix3D c = new Matrix3D(size);
		if (a.getSize() != this.getSize()) {
			throw new MatrixException("Error in sum! Sizes of matrices do not match!");
		}
		for (int i = 0; i < size; ++i)
			for (int j = 0; j < size; ++j)
				for (int k = 0; k < size; ++k)
					c.setElement(a.getElement(i, j, k) + this.getElement(i, j, k), i, j, k); 
		return c;
	}
	
	/**
	 *  Kivonja a memoriaban talalhato matrixunkbol a parameterkent megadott matrixot.*/
	public Matrix3D difference(Matrix3D a) throws MatrixException {
		Matrix3D c = new Matrix3D(size);
		if (a.getSize() != this.getSize()) {
			throw new MatrixException("Error in difference! Sizes of matrices do not match!");
		}
		for (int i = 0; i < size; ++i)
			for (int j = 0; j < size; ++j)
				for (int k = 0; k < size; ++k)
					c.setElement(a.getElement(i, j, k) - this.getElement(i, j, k), i, j, k); 
		return c;
	}
	/**
	 * Matrix kiiratasa a konzolra.*/
	public void printMatrix() {
		for (int k = 0; k < size; ++k) {
			for (int i = 0; i < size; ++i) {				
				 for (int j = 0; j < size; ++j)
					System.out.print(getElement(i,j,k) + " ");
				System.out.println();
			}
			System.out.println();
		}
	}
	/**
	 * Matrix beolvasasa file-bol.
	 * String fileName - forras file neve, relativ eleresi utvonal*/
	public void readMatrixFromFile(String fileName) throws MatrixException {
		try {
			FileReader input = new FileReader(fileName);
			BufferedReader in = new BufferedReader(input);
			String s  = in.readLine();
			int n = Integer.parseInt(s);	//a file elejen a matrix merete van
			if (size != n)
				throw new MatrixException("Error reading from file: size in file doesn't match with matrix size!");
			int i = 0, j = 0;
			for (int k = 0; k < size; ++k) {
				in.readLine();				//utanna egy ures sor
				for (i = 0; i < size; ++i) {
					s = in.readLine();
					String [] array = s.split(" ");	//soronkent <space>-el elvalasztva az elemek
					if (array.length != size)
						throw new MatrixException("Error reading from file: line length doesn't match with matrix size!");
					for (j = 0; j < size; ++j) {
						n = Integer.parseInt(array[j]);
						this.setElement(n, i, j, k);
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Ellenorzi, hogy egy adott szamnal a matrix minden eleme legyen kissebb.
	 * int bound - kuszobszam
	 * return:
	 * true - ha minden elem kisebb minde a kuszobszam*/
	public boolean checkBound(int bound) {
		for (int k = 0; k < size; ++k)
			for (int i = 0; i < size; ++i)
				for (int j = 0; j < size; ++j)				
					if (bound < getElement(i, j, k))
						return false;
		return true;
	}
	
	public int getElement(int i, int j, int k) {
		return matrix[i][j][k];
	}
	
	public void setElement(int number, int i, int j, int k) {
		matrix[i][j][k] = number;
	}	
	
	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public int[][][] getMatrix() {
		return matrix;
	}

	public void setMatrix(int[][][] matrix) {
		this.matrix = matrix;
	}

	/**
	 * Inicializalja a 3dMatrixot 0-al.
	*/
	public void init(){
		for (int i = 0; i < size; ++i)
			for (int j = 0; j < size; ++j)
				for (int k = 0; k < size; ++k)
					setElement(0,i,j,k);
	}
}
